/**
 * WebSocket服务
 * 用于处理前端与WebSocket服务器的实时通信
 */

export interface WebSocketMessage {
  type: string;
  data?: any;
  timestamp?: number;
}

export interface WebSocketChatRequest {
  message: string;
  conversation_id?: string;
  model?: string;
  use_knowledge_base?: boolean;
  mode?: string;
}

export interface WebSocketChatResponse {
  type: 'connection_established' | 'chat_chunk' | 'chat_complete' | 'error' | 'pong';
  data?: any;
  message?: string;
  timestamp: number;
}

export class WebSocketService {
  private ws: WebSocket | null = null;
  private reconnectAttempts = 0;
  private maxReconnectAttempts = 5;
  private reconnectDelay = 1000;
  private messageHandlers: Map<string, Function[]> = new Map();
  private connectionPromise: Promise<void> | null = null;
  private connectionResolve: (() => void) | null = null;
  private connectionReject: ((error: Error) => void) | null = null;

  constructor(private url: string = 'ws://localhost:3003/ws/chat') {}

  /**
   * 连接到WebSocket服务器
   */
  async connect(): Promise<void> {
    if (this.ws?.readyState === WebSocket.OPEN) {
      return Promise.resolve();
    }

    if (this.connectionPromise) {
      return this.connectionPromise;
    }

    this.connectionPromise = new Promise((resolve, reject) => {
      this.connectionResolve = resolve;
      this.connectionReject = reject;

      try {
        this.ws = new WebSocket(this.url);

        this.ws.onopen = () => {
          console.log('✅ WebSocket连接已建立');
          this.reconnectAttempts = 0;
          this.connectionResolve?.();
          this.connectionResolve = null;
          this.connectionReject = null;
          this.connectionPromise = null;
          this.emit('connected');
        };

        this.ws.onmessage = (event) => {
          try {
            const message: WebSocketChatResponse = JSON.parse(event.data);
            this.emit(message.type, message);
          } catch (error) {
            console.error('WebSocket消息解析错误:', error);
          }
        };

        this.ws.onclose = (event) => {
          console.log('🔌 WebSocket连接关闭:', event.code, event.reason);
          this.emit('disconnected');
          this.attemptReconnect();
        };

        this.ws.onerror = (error) => {
          console.error('❌ WebSocket错误:', error);
          this.connectionReject?.(new Error('WebSocket连接失败'));
          this.connectionResolve = null;
          this.connectionReject = null;
          this.connectionPromise = null;
          this.emit('error', error);
        };

      } catch (error) {
        this.connectionReject?.(error as Error);
        this.connectionResolve = null;
        this.connectionReject = null;
        this.connectionPromise = null;
      }
    });

    return this.connectionPromise;
  }

  /**
   * 断开WebSocket连接
   */
  disconnect(): void {
    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
    this.reconnectAttempts = this.maxReconnectAttempts;
  }

  /**
   * 发送消息到WebSocket服务器
   */
  async send(message: WebSocketMessage): Promise<void> {
    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
      await this.connect();
    }

    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(message));
    } else {
      throw new Error('WebSocket连接不可用');
    }
  }

  /**
   * 发送聊天消息
   */
  async sendChatMessage(request: WebSocketChatRequest): Promise<void> {
    const message: WebSocketMessage = {
      type: 'chat_message',
      data: request,
      timestamp: Date.now()
    };
    return this.send(message);
  }

  /**
   * 发送ping消息
   */
  async ping(): Promise<void> {
    const message: WebSocketMessage = {
      type: 'ping',
      timestamp: Date.now()
    };
    return this.send(message);
  }

  /**
   * 注册消息处理器
   */
  on(messageType: string, handler: Function): void {
    if (!this.messageHandlers.has(messageType)) {
      this.messageHandlers.set(messageType, []);
    }
    this.messageHandlers.get(messageType)?.push(handler);
  }

  /**
   * 移除消息处理器
   */
  off(messageType: string, handler: Function): void {
    const handlers = this.messageHandlers.get(messageType);
    if (handlers) {
      const index = handlers.indexOf(handler);
      if (index > -1) {
        handlers.splice(index, 1);
      }
    }
  }

  /**
   * 触发消息事件
   */
  private emit(messageType: string, data?: any): void {
    const handlers = this.messageHandlers.get(messageType);
    if (handlers) {
      handlers.forEach(handler => handler(data));
    }
  }

  /**
   * 尝试重新连接
   */
  private attemptReconnect(): void {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.log('❌ 达到最大重连次数，停止重连');
      return;
    }

    this.reconnectAttempts++;
    const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);

    console.log(`🔄 将在 ${delay}ms 后尝试第 ${this.reconnectAttempts} 次重连...`);

    setTimeout(() => {
      if (this.ws?.readyState !== WebSocket.OPEN) {
        this.connect().catch(error => {
          console.error('重连失败:', error);
        });
      }
    }, delay);
  }

  /**
   * 获取连接状态
   */
  getState(): string {
    if (!this.ws) return 'disconnected';
    switch (this.ws.readyState) {
      case WebSocket.CONNECTING: return 'connecting';
      case WebSocket.OPEN: return 'connected';
      case WebSocket.CLOSING: return 'closing';
      case WebSocket.CLOSED: return 'disconnected';
      default: return 'unknown';
    }
  }

  /**
   * 检查是否已连接
   */
  isConnected(): boolean {
    return this.ws?.readyState === WebSocket.OPEN;
  }
}

// 创建全局WebSocket服务实例
export const webSocketService = new WebSocketService();